#include "mainwindow.h"
#include "ui_mainwindow.h"

double xX[8], Xx[8];

MainWindow::MainWindow(QApplication *app, Geocaching *prog, QWidget *parent) :
    QMainWindow(parent), ui(new Ui::MainWindow), myApp(app), myProg(prog),\
    gpsStatusLabel(new QLabel(cGPSOFF)), gpsCoordLabel(new QLabel(cNOTCOORDS)), myCoordLabel(new QLabel(cNOTMAP)), trackLabel(new QLabel(cTRACKOFF)),\
    plForm(NULL), rlForm(NULL), mlForm(NULL), tlForm(NULL), currentCursorPos(), mainwindowScene(parent),\
    currentRouteLines(), currentTrackPointList(), currentTrackLines(), mainWayPointList(), mainCurrentPoint(NULL),\
    pointVisibility(false), routeVisibility(false), trackVisibility(false), currPointVisibility(false)
{
    ui->setupUi(this);
    // главное меню
    connect(ui->action_createmap,   SIGNAL(triggered()),    this,   SLOT(CreateMapDialogShow()));           // Карты -> Создать карту
    connect(ui->action_editmap,     SIGNAL(triggered()),    this,   SLOT(EditMapDialogShow()));             // Карты -> Редактировать карту
    connect(ui->action_closemap,    SIGNAL(triggered()),    this,   SLOT(CloseMap()));                      // Карты -> Закрыть карту
    connect(ui->action_deletemap,   SIGNAL(triggered()),    this,   SLOT(DeleteMap()));                     // Карты -> Удалить карту
    connect(ui->action_maplist,     SIGNAL(triggered()),    this,   SLOT(MapListFormShow()));               // Карты -> Список карт
    connect(ui->action_addpoint,    SIGNAL(triggered()),    this,   SLOT(AddPointDialogShow()));            // Точки -> Добавить точку
    connect(ui->action_pointlist,   SIGNAL(triggered()),    this,   SLOT(PointListFormShow()));             // Точки -> Список точек
    connect(ui->action_addroute,    SIGNAL(triggered()),    this,   SLOT(AddRouteDialogShow()));            // Маршруты -> Добавить маршрут
    connect(ui->action_routelist,   SIGNAL(triggered()),    this,   SLOT(RouteListFormShow()));             // Маршруты -> Список маршрутов
    connect(ui->action_manualtrack, SIGNAL(triggered()),    this,   SLOT(ManualRecordTrack()));             // Треки -> Ручная запись трека
    connect(ui->action_autotrack,   SIGNAL(triggered()),    this,   SLOT(AutoRecordTrack()));               // Треки -> Автоматическая запись трека
    connect(ui->action_tracklist,   SIGNAL(triggered()),    this,   SLOT(TrackListFormShow()));             // Треки -> Список треков
    connect(ui->action_gpssetup,    SIGNAL(triggered()),    this,   SLOT(SetupGPSShow()));                  // GPS-приёмник -> Настройки
    connect(ui->action_gpsonoff,    SIGNAL(triggered()),    this,   SLOT(SwitchGPS()));                     // GPS-приёмник -> Включить приёмник
    connect(ui->action_viewpoints,  SIGNAL(toggled(bool)),  this,   SLOT(SetAllWayPointVisible(bool)));     // Вид -> Отображение точек
    connect(ui->action_viewroute,   SIGNAL(toggled(bool)),  this,   SLOT(SetAllRouteVisible(bool)));        // Вид -> Отображение маршрута
    connect(ui->action_viewtrack,   SIGNAL(toggled(bool)),  this,   SLOT(SetAllTrackPointVisible(bool)));   // Вид -> Отображение треков
    connect(ui->action_currpoint,   SIGNAL(toggled(bool)),  this,   SLOT(SetCurrPointVisible(bool)));       // Вид -> Отображение текущего местоположения
    connect(ui->action_help,        SIGNAL(triggered()),    this,   SLOT(HelpShow()));                      // Справка -> Помощь
    connect(ui->action_about,       SIGNAL(triggered()),    this,   SLOT(AboutShow()));                     // Справка -> О программе
    // сигналы класса Geocaching
    connect(myProg, SIGNAL(PointAdded(Point)),      this, SLOT(AddWayPoint(Point)));
    connect(myProg, SIGNAL(PointEdited(Point)),     this, SLOT(EditWayPoint(Point)));
    connect(myProg, SIGNAL(PointDeleted(ulong)),    this, SLOT(DeleteWayPoint(ulong)));
    connect(myProg, SIGNAL(CurrentMapChanged()),    this, SLOT(UpdateCurrentMap()));
    connect(myProg, SIGNAL(CurrentRouteChanged()),  this, SLOT(UpdateCurrentRoute()));
    connect(myProg, SIGNAL(CurrentTrackChanged()),  this, SLOT(UpdateCurrentTrack()));
    // карта и контекстное меню
    ui->graphicsView->setScene(&mainwindowScene);
    connect(ui->action_addmanualtrackpoint, SIGNAL(triggered()), this, SLOT(AddManualTrackPoint()));
    connect(ui->action_stopautotrack,       SIGNAL(triggered()), this, SLOT(StopAutoTrackDialogShow()));
    connect(ui->action_stopmanualtrack,     SIGNAL(triggered()), this, SLOT(StopManualTrackDialogShow()));
    ui->graphicsView->addAction(ui->action_addpoint);   // Добавить точку
    ui->graphicsView->addAction(ui->action_addroute);   // Добавить маршрут
    ui->graphicsView->addAction(ui->action_addmanualtrackpoint);
    ui->graphicsView->addAction(ui->action_stopmanualtrack);
    ui->graphicsView->addAction(ui->action_stopautotrack);
    ui->graphicsView->setContextMenuPolicy(Qt::ActionsContextMenu);
    // строка состояния
    connect(&mainwindowScene, SIGNAL(mainSceneMouseMove(QPoint)), this, SLOT(UpdateCursorPosition(QPoint)));
    connect(myProg, SIGNAL(CoordinatesChanged()), this, SLOT(UpdateGPSStatus()));
    myCoordLabel->setAlignment(Qt::AlignCenter);
    gpsStatusLabel->setAlignment(Qt::AlignCenter);
    gpsCoordLabel->setAlignment(Qt::AlignCenter);
    trackLabel->setAlignment(Qt::AlignCenter);
    ui->mainStatusBar->addWidget(myCoordLabel);
    ui->mainStatusBar->addWidget(gpsStatusLabel);
    ui->mainStatusBar->addWidget(gpsCoordLabel);
    ui->mainStatusBar->addWidget(trackLabel);
/*
    // ТЕСТИРОВАНИЕ
    unsigned long N = 5;
    QString tmpstr;
    Route *tmpRoute = new Route(tmpstr.sprintf("%s", cUNNAMED));
    for(unsigned long i = 0; i < N; ++i)
    {
        Point *tmpPoint = new Point(tmpstr.sprintf("%s%lu", cUNNAMED, i));

        // Военмех
        //tmpPoint->SetCoordinates(59.9163 + i*0.0002, 30.308 + i*0.002);

        // Северо-Восток
        tmpPoint->SetCoordinates(60.025 + i*0.0002+0.003*i*qSin(i*i), 30.412 + i*0.002+0.001*i*qCos(i*i));

        qsrand(100*i*i);
        for (int ind=0;ind<qrand()%10+1;ind++)
        {
            qsrand(qrand()%10+1*i);
            tmpPoint->AddFile(QString::number(qrand()));
        }

        myProg->AddPoint(tmpPoint);
        tmpRoute->AddPoint(tmpPoint->GetID());
    }
    myProg->AddRoute(tmpRoute);
    // ТЕСТИРОВАНИЕ
*/
}
MainWindow::~MainWindow()
{
    if(mainCurrentPoint)    delete mainCurrentPoint;
    if(plForm)              delete plForm;
    if(rlForm)              delete rlForm;
    if(mlForm)              delete mlForm;
    if(tlForm)              delete tlForm;
    if(gpsStatusLabel)      delete gpsStatusLabel;
    if(gpsCoordLabel)       delete gpsCoordLabel;
    if(myCoordLabel)        delete myCoordLabel;
    if(trackLabel)          delete trackLabel;
    currentRouteLines.clear();
    currentTrackPointList.clear();
    currentTrackLines.clear();
    mainWayPointList.clear();
    delete ui;
}

double MainWindow::transformx(double m[8], double x, double y)
{
    if(myProg->GetCurrentMapID())   return (m[0]*x+m[1]*y+m[2])/(m[6]*x+m[7]*y+1);
    else                            return 0;
}

double MainWindow::transformy(double m[8], double x, double y)
{
    if(myProg->GetCurrentMapID())   return (m[3]*x+m[4]*y+m[5])/(m[6]*x+m[7]*y+1);
    else                            return 0;
}

void MainWindow::UpdateSize(void)
{
    int width = 0, height = 0;
    ui->graphicsView->adjustSize();
    ui->mainStatusBar->adjustSize();
    width = (ui->mainStatusBar->width() > ui->graphicsView->width()) ? ui->mainStatusBar->width() : ui->graphicsView->width() + cINTERVAL;
    height = ui->mainStatusBar->height() + ui->mainToolBar->height() + ui->menuBar->height() + ui->graphicsView->height() + cINTERVAL;
    resize(width, height);
}
// ----------------------------------------------------------------------------------------------
// Функции для работы с точками

void MainWindow::AddPointDialogShow(void)
{
    double x = 0, y = 0;
    if(myProg->GetCurrentMapID())
    {
        x = transformy(xX, currentCursorPos.x(), currentCursorPos.y());
        y = transformx(xX, currentCursorPos.x(), currentCursorPos.y());
    }
    AddPointDialog apDialog(x, y);
    apDialog.setWindowFlags(apDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(apDialog.exec())
    {
        Point tmpPoint;
        if(apDialog.Result(&tmpPoint))
            myProg->AddPoint(&tmpPoint);
    }
}

void MainWindow::EditPointDialogShow(const unsigned long &aID)
{
    Point tmpPoint;
    myProg->GetPoint(aID, &tmpPoint);
    EditPointDialog epDialog(&tmpPoint);
    epDialog.setWindowFlags(epDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(epDialog.exec())
        if(epDialog.Result())
            myProg->EditPoint(aID, &tmpPoint);
}

void MainWindow::PointListFormShow(void)
{
    if(!plForm) plForm = new PointListForm(myProg);
    plForm->show();
    plForm->activateWindow();
}

// ----------------------------------------------------------------------------------------------
// Функции для работы с маршрутами

void MainWindow::AddRouteDialogShow(void) const
{
    AddRouteDialog arDialog(myProg->GetPointList());
    arDialog.setWindowFlags(arDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(arDialog.exec())
    {
        Route tmpRoute;
        bool setCurrent = false;
        if(arDialog.Result(&tmpRoute, setCurrent))
            myProg->AddRoute(&tmpRoute, setCurrent);
    }
}

void MainWindow::RouteListFormShow(void)
{
    if(!rlForm) rlForm = new RouteListForm(myProg);
    rlForm->show();
    rlForm->activateWindow();
}

// ----------------------------------------------------------------------------------------------
// Функции для работы с картами

void MainWindow::CreateMapDialogShow(void)
{
    CreateMapDialog cmDialog;
    cmDialog.setWindowFlags(cmDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(cmDialog.exec())
    {
        Map tmpMap;
        bool setCurrent = false;
        if(cmDialog.Result(&tmpMap, setCurrent))
            myProg->AddMap(&tmpMap, setCurrent);
    }
}

void MainWindow::EditMapDialogShow(void)
{
    Map currMap;
    if(myProg->GetCurrentMap(&currMap))
    {
        EditMapDialog emDialog(&currMap, true);
        emDialog.setWindowFlags(emDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
        if(emDialog.exec())
        {
            bool setCurrent = false;
            if(emDialog.Result(setCurrent))
                myProg->EditMap(currMap.GetID(), &currMap, setCurrent);
        }
    }
}

void MainWindow::MapListFormShow(void)
{
    if(!mlForm) mlForm = new MapListForm(myProg);
    mlForm->show();
    mlForm->activateWindow();
}

void MainWindow::CloseMap(void)
{
    myProg->SetCurrentMap(0);
}

void MainWindow::DeleteMap(void)
{
    myProg->DeleteMap(myProg->GetCurrentMapID());
}

// ----------------------------------------------------------------------------------------------
// Функции для работы с треками

void MainWindow::TrackListFormShow(void)
{
    if(!tlForm) tlForm = new TrackListForm(myProg);
    tlForm->show();
    tlForm->activateWindow();
}

void MainWindow::AutoRecordTrack(void)
{
    if(myProg->GetAutoTrackStatus())
        StopAutoTrackDialogShow();
    else
    {
        GeoCoordinates tmpCoord;
        if(myProg->GetGPSStatus() == GPSon && myProg->GetCoordinates(tmpCoord))
        {
            myProg->StartAutoTrackRecord();
            ui->action_stopautotrack->setVisible(true);
        }
    }
    ui->action_autotrack->setChecked(myProg->GetAutoTrackStatus());
    UpdateTrackStatus();
}

void MainWindow::StopAutoTrackDialogShow(const bool &aContinue)
{
    if(!myProg->GetAutoTrackStatus()) return;
    CreateTrackDialog ctDialog(aContinue);
    ctDialog.setWindowFlags(ctDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(ctDialog.exec())
    {
        QString tmpString;
        bool save = false, setCurrent = false;;
        if(ctDialog.Result(tmpString, save, setCurrent))
        {
            myProg->StopAutoTrackRecord(tmpString, save, setCurrent);
            ui->action_stopautotrack->setVisible(false);
            ui->action_autotrack->setChecked(false);
            UpdateTrackStatus();
        }
    }
}

void MainWindow::ManualRecordTrack(void)
{
    if(myProg->GetManualTrackStatus())
        StopManualTrackDialogShow();
    else
    {
        GeoCoordinates tmpCoord;
        if(myProg->GetGPSStatus() == GPSon && myProg->GetCoordinates(tmpCoord))
        {
            myProg->StartManualTrackRecord();
            ui->action_stopmanualtrack->setVisible(true);
            ui->action_addmanualtrackpoint->setVisible(true);
        }
    }
    ui->action_manualtrack->setChecked(myProg->GetManualTrackStatus());
    UpdateTrackStatus();
}

void MainWindow::AddManualTrackPoint(void)
{
    if(myProg->GetGPSStatus() == GPSon)
        myProg->AddManualTrackPoint();
    else
        ui->action_manualtrack->setChecked(false);
}

void MainWindow::StopManualTrackDialogShow(const bool &aContinue)
{
    if(!myProg->GetManualTrackStatus()) return;
    CreateTrackDialog ctDialog(aContinue);
    ctDialog.setWindowFlags(ctDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(ctDialog.exec())
    {
        QString tmpString;
        bool save = false, setCurrent = false;;
        if(ctDialog.Result(tmpString, save, setCurrent))
        {
            myProg->StopManualTrackRecord(tmpString, save, setCurrent);
            ui->action_stopmanualtrack->setVisible(false);
            ui->action_addmanualtrackpoint->setVisible(false);
            ui->action_manualtrack->setChecked(false);
            UpdateTrackStatus();
        }
    }
}
// ----------------------------------------------------------------------------------------------
// Функции для работы с GPS-приёмником

void MainWindow::SwitchGPS(void)
{
    myProg->SwitchGPS(myProg->GetGPSStatus() == GPSoff);
    UpdateGPSStatus();
}

void MainWindow::SetupGPSShow(void)
{
    SetupGPSDialog sgDialog;
    sgDialog.setWindowFlags(sgDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    if(sgDialog.exec())
    {
        SerialPortSettings tmpSettings;
        QString tmpString;
        bool Start = false;
        if(sgDialog.Result(tmpSettings, tmpString, Start))
        {
            if(myProg->SetupGPS(tmpSettings, tmpString))
            {
                ui->action_gpsonoff->setEnabled(true);
                myProg->SwitchGPS(Start);
            }
            else
            {
                ui->action_gpsonoff->setEnabled(false);
                myProg->SwitchGPS(false);
            }
        }
    }
    UpdateGPSStatus();
}
// ----------------------------------------------------------------------------------------------
// Функции меню "Справка"

void MainWindow::HelpShow(void) const
{
    QString file_name = cHELPFILE;
    if(!QFile::exists(file_name))
        {
            QMessageBox::warning(QApplication::activeWindow(), QApplication::applicationName(),
            "Невозможно открыть файл `" + file_name + "`. Файл не существует!");
            return;
        }
    if(!QDesktopServices::openUrl(QUrl(QUrl::fromLocalFile(file_name))))
        {
            QMessageBox::information(QApplication::activeWindow(), QApplication::applicationName(),
            "Невозможно открыть файл `" + file_name + "`. Не найдена программа для его открытия!");
            return;
        }
}

void MainWindow::AboutShow(void) const
{
    AboutDialog aboutDialog;
    aboutDialog.setWindowFlags(aboutDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    aboutDialog.exec();
}
// ----------------------------------------------------------------------------------------------
// Функции для работы с точками на карте

void MainWindow::AddWayPoint(const Point &aPoint)
{
    Map currMap;
    myProg->GetCurrentMap(&currMap);
    if(myProg->GetCurrentMapID() && currMap.CheckBorder(aPoint.GetCoordinates()))
    {
        WayPointWidget *tmpWPWidget = new WayPointWidget(aPoint.GetID());
        tmpWPWidget->setItem(mainwindowScene.addWidget(tmpWPWidget));
        tmpWPWidget->setOwnVisibility(pointVisibility);
        tmpWPWidget->setPosition(transformx(Xx, aPoint.GetCoordinates().GetLongitude(), aPoint.GetCoordinates().GetLatitude()) - cPOINTSIZE/2,
                                 transformy(Xx, aPoint.GetCoordinates().GetLongitude(), aPoint.GetCoordinates().GetLatitude()) - cPOINTSIZE/2);
        mainWayPointList.push_back(tmpWPWidget);
        connect(tmpWPWidget, SIGNAL(Edited(ulong)), this, SLOT(EditPointDialogShow(ulong)));
    }
}

void MainWindow::EditWayPoint(const Point &aPoint)
{
    unsigned long tmpID = aPoint.GetID(), N = mainWayPointList.size();
    for(unsigned long i = 0; i < N; ++i)
        if(mainWayPointList[i]->ID == tmpID)
        {
            Map currMap;
            myProg->GetCurrentMap(&currMap);
            mainWayPointList[i]->setOwnVisibility(pointVisibility && myProg->GetCurrentMapID() && currMap.CheckBorder(aPoint.GetCoordinates()));
            mainWayPointList[i]->setPosition(transformx(Xx, aPoint.GetCoordinates().GetLongitude(), aPoint.GetCoordinates().GetLatitude()) - cPOINTSIZE/2,
                                             transformy(Xx, aPoint.GetCoordinates().GetLongitude(), aPoint.GetCoordinates().GetLatitude()) - cPOINTSIZE/2);
            return;
        }
    AddWayPoint(aPoint);
}

void MainWindow::DeleteWayPoint(const unsigned long &aID)
{
    unsigned long N = mainWayPointList.size();
    for(unsigned long i = 0; i < N; ++i)
        if(mainWayPointList[i]->ID == aID)
        {
            delete mainWayPointList[i];
            mainWayPointList.removeAt(i);
            return;
        }
}

void MainWindow::UpdateCurrentRoute(void)
{
    foreach(QGraphicsLineItem *item, currentRouteLines)
        if(item && item->scene())
            mainwindowScene.removeItem(item);
    currentRouteLines.clear();
    foreach(WayPointWidget *item, mainWayPointList)
        if(item)
        {
            item->state = NotRoute;
            item->setOwnVisibility(pointVisibility);
        }
    Route currRoute;
    if(myProg->GetCurrentRoute(&currRoute) && myProg->GetCurrentMapID())
    {
        QList <unsigned long> currentRoutePoints;
        ui->action_viewroute->setChecked(myProg->GetCurrentMapID());
        unsigned long N = currRoute.GetPointCount();
        for(unsigned long i = 0; i < N; ++i)
        {
            unsigned long tmpID = currRoute.GetPoint(i);
            unsigned long K = mainWayPointList.size();
            for(unsigned long j = 0; j < K; ++j)
                if(mainWayPointList[j]->ID == tmpID)
                {
                    if(i)
                    {
                        if(i == N - 1)  mainWayPointList[j]->state = EndPoint;
                        else            mainWayPointList[j]->state = MiddlePoint;
                    }
                    else
                        mainWayPointList[j]->state = FirstPoint;
                    currentRoutePoints.push_back(j);
                    mainWayPointList[j]->setOwnVisibility(myProg->GetCurrentMapID());
                }
        }
        // создание линий
        N = currentRoutePoints.size();
        if(N > 1)
            for(unsigned long i = 0; i < N - 1; ++i)
            {
                currentRouteLines.push_back(mainwindowScene.addLine(mainWayPointList[currentRoutePoints[i]]->getX() + cPOINTSIZE/2,
                                                                    mainWayPointList[currentRoutePoints[i]]->getY() + cPOINTSIZE/2,
                                                                    mainWayPointList[currentRoutePoints[i+1]]->getX() + cPOINTSIZE/2,
                                                                    mainWayPointList[currentRoutePoints[i+1]]->getY() + cPOINTSIZE/2));
                currentRouteLines.last()->setZValue(cLINEZVALUE);
                currentRouteLines.last()->setVisible(myProg->GetCurrentMapID() && (mainWayPointList[currentRoutePoints[i]]->isVisible() &&
                                                                                   mainWayPointList[currentRoutePoints[i+1]]->isVisible()));
            }
    }
}

void MainWindow::UpdateCurrentTrack(void)
{
    foreach(TrackPointWidget *item, currentTrackPointList)
        delete item;
    currentTrackPointList.clear();
    foreach(QGraphicsLineItem *item, currentTrackLines)
        if(item && item->scene())
            mainwindowScene.removeItem(item);
    currentTrackLines.clear();
    Track currTrack;
    Map currMap;
    if(myProg->GetCurrentTrack(&currTrack) && myProg->GetCurrentMap(&currMap))
    {
        ui->action_viewtrack->setChecked(true);
        unsigned long tmpID = currTrack.GetID();
        unsigned long N = currTrack.GetPointCount();
        for(unsigned long i = 0; i < N; i++)
        {
            TrackPoint tmpTrackPoint;
            currTrack.GetPoint(&tmpTrackPoint, i);
            TrackPointWidget *tmpTPWidget = new TrackPointWidget(i, tmpID);
            if(currMap.CheckBorder(tmpTrackPoint.GetCoordinates()))
            {
                tmpTPWidget->setItem(mainwindowScene.addWidget(tmpTPWidget));
                tmpTPWidget->setOwnVisibility(trackVisibility);
                tmpTPWidget->setPosition(transformx(Xx, tmpTrackPoint.GetCoordinates().GetLongitude(), tmpTrackPoint.GetCoordinates().GetLatitude()) - cTRACKPOINTSIZE/2,
                                         transformy(Xx, tmpTrackPoint.GetCoordinates().GetLongitude(), tmpTrackPoint.GetCoordinates().GetLatitude()) - cTRACKPOINTSIZE/2),
                currentTrackPointList.push_back(tmpTPWidget);
            }
        }
        // создание линий
        N = currentTrackPointList.size();
        if(N > 1)
            for(unsigned long i = 0; i < N - 1; ++i)
            {
                currentTrackLines.push_back(mainwindowScene.addLine(currentTrackPointList[i]->getX() + cPOINTSIZE/2,
                                                                    currentTrackPointList[i]->getY() + cPOINTSIZE/2,
                                                                    currentTrackPointList[i+1]->getX() + cPOINTSIZE/2,
                                                                    currentTrackPointList[i+1]->getY() + cPOINTSIZE/2));
                currentTrackLines.last()->setZValue(cLINEZVALUE);
                currentTrackLines.last()->setVisible((currentTrackPointList[i]->isVisible() && currentTrackPointList[i+1]->isVisible()));
            }
    }
}

void MainWindow::SetCurrPointVisible(const bool &aVisible)
{
    Map currMap;
    currPointVisibility = aVisible && myProg->GetCurrentMap(&currMap);
    ui->action_currpoint->setChecked(currPointVisibility);
    if(mainCurrentPoint)
    {
        GeoCoordinates tmpCoord;
        bool isCoord = myProg->GetCoordinates(tmpCoord);
        mainCurrentPoint->setPosition(transformx(Xx, tmpCoord.GetLongitude(), tmpCoord.GetLatitude()) - cCURRPOINTSIZE/2,
                                      transformy(Xx, tmpCoord.GetLongitude(), tmpCoord.GetLatitude()) - cCURRPOINTSIZE/2);
        mainCurrentPoint->setOwnVisibility(currPointVisibility && isCoord && currMap.CheckBorder(tmpCoord));
    }
}

void MainWindow::SetAllRouteVisible(const bool &aVisible)
{
    routeVisibility = aVisible && myProg->GetCurrentMapID();
    ui->action_viewroute->setChecked(routeVisibility);
    foreach(QGraphicsLineItem *item, currentRouteLines)
        item->setVisible(routeVisibility);
    Route currRoute;
    if(myProg->GetCurrentRoute(&currRoute) && routeVisibility)
    {
        unsigned long N = currRoute.GetPointCount();
        for(unsigned long i = 0; i < N; ++i)
        {
            unsigned long tmpID = currRoute.GetPoint(i);
            foreach(WayPointWidget *item, mainWayPointList)
            {
                if(item->ID == tmpID)
                {
                    if(i)
                    {
                        if(i == N - 1)  item->state = EndPoint;
                        else            item->state = MiddlePoint;
                    }
                    else
                        item->state = FirstPoint;
                }
                item->setOwnVisibility(true);
            }
        }
    }
    else
        foreach(WayPointWidget *item, mainWayPointList)
        {
            item->state = NotRoute;
            item->setOwnVisibility(pointVisibility);
        }
}

void MainWindow::SetAllWayPointVisible(const bool &aVisible)
{
    pointVisibility = aVisible && myProg->GetCurrentMapID();
    ui->action_viewpoints->setChecked(pointVisibility);
    Route currRoute;
    bool isCurrRoute = myProg->GetCurrentRoute(&currRoute);
    foreach(WayPointWidget* tmpWayPoint, mainWayPointList)
        tmpWayPoint->setOwnVisibility(pointVisibility || (isCurrRoute && currRoute.IsPointBelong(tmpWayPoint->ID) && routeVisibility));
}

void MainWindow::SetAllTrackPointVisible(const bool &aVisible)
{
    trackVisibility = aVisible && myProg->GetCurrentMapID();
    ui->action_viewtrack->setChecked(trackVisibility);
    unsigned long currentTrackID = myProg->GetCurrentTrackID();
    foreach(TrackPointWidget* tmpTrackPointWidget, currentTrackPointList)
        tmpTrackPointWidget->setOwnVisibility(currentTrackID && trackVisibility);
    foreach(QGraphicsLineItem *item, currentTrackLines)
        item->setVisible(currentTrackID && trackVisibility);
}

// ----------------------------------------------------------------------------------------------
// Функции обновления строки состояния

void MainWindow::UpdateCursorPosition(QPoint cursorPos)
{
    QString tmpString;
    if(myProg->GetCurrentMapID())
    {
        currentCursorPos = cursorPos;
        tmpString.sprintf("%sширота %lf  долгота %lf", cMYCOORDS,
                          transformy(xX, currentCursorPos.x(), currentCursorPos.y()),
                          transformx(xX, currentCursorPos.x(), currentCursorPos.y()));
    }
    else
        tmpString = cNOTMAP;
    myCoordLabel->setText(tmpString);
}

void MainWindow::UpdateTrackStatus(void)
{
    QString tmpString;
    // состояние записи трека
    bool autoTrack = myProg->GetAutoTrackStatus(), manualTrack = myProg->GetManualTrackStatus();
    if(autoTrack || manualTrack)
    {
        tmpString.sprintf("%s%s%s%s", cTRACKON,
                            autoTrack?cTRACKAUTO:"",
                            (autoTrack&&manualTrack)?",":"",
                            manualTrack?cTRACKMANUAL:"");
    }
    else
        tmpString = cTRACKOFF;
    trackLabel->setText(tmpString);
}

void MainWindow::UpdateGPSStatus(void)
{
    GeoCoordinates tmpCoord;
    if(myProg->GetGPSStatus() == GPSon)
    {
        ui->action_gpsinfo->setEnabled(true);
        gpsStatusLabel->setText(cGPSON);
        ui->action_gpsonoff->setText("Выключить приёмник");
        if(myProg->GetCoordinates(tmpCoord))
        {
            QString tmpString;
            Map currMap;
            myProg->GetCurrentMap(&currMap);
            tmpString.sprintf("%sширота %lf  долгота %lf", cGPSCOORDS, tmpCoord.GetLatitude(), tmpCoord.GetLongitude());
            gpsCoordLabel->setText(tmpString);
            if(mainCurrentPoint)
            {
                mainCurrentPoint->setPosition(transformx(Xx, tmpCoord.GetLongitude(), tmpCoord.GetLatitude()) - cCURRPOINTSIZE/2,
                                              transformy(Xx, tmpCoord.GetLongitude(), tmpCoord.GetLatitude()) - cCURRPOINTSIZE/2);
                mainCurrentPoint->setOwnVisibility(myProg->GetCurrentMapID() && currPointVisibility && currMap.CheckBorder(tmpCoord));
            }
        }
        else
        {
            if(mainCurrentPoint)    mainCurrentPoint->setOwnVisibility(false);
            gpsCoordLabel->setText(cNOTCOORDS);
        }
    }
    else
    {
        ui->action_gpsinfo->setEnabled(false);
        gpsStatusLabel->setText(cGPSOFF);
        ui->action_gpsonoff->setText("Включить приёмник");
        if(mainCurrentPoint)    mainCurrentPoint->setOwnVisibility(false);
        gpsCoordLabel->setText(cNOTCOORDS);
        StopAutoTrackDialogShow(false);
        StopManualTrackDialogShow(false);
    }
    UpdateTrackStatus();
}

void MainWindow::UpdateCurrentMap(void)
{
    if(mainCurrentPoint)    delete mainCurrentPoint;
    foreach(WayPointWidget *item, mainWayPointList)
        delete item;
    mainWayPointList.clear();
    mainwindowScene.clear();
    // текущее местоположение
    mainCurrentPoint = new CurrentPointWidget;
    mainCurrentPoint->setItem(mainwindowScene.addWidget(mainCurrentPoint));
    mainCurrentPoint->setOwnVisibility(false);
    Map currMap;
    if(myProg->GetCurrentMap(&currMap))
    {
        for(int i = 0; i < 8; ++i)
        {
            xX[i] = currMap.xXkoef[i];
            Xx[i] = currMap.Xxkoef[i];
        }
        // Смена изображения карты
        QPixmap mainPicture;
        mainPicture.load(currMap.GetFilePath());
        mainwindowScene.setSceneRect(mainPicture.rect());
        mainwindowScene.addPixmap(mainPicture);
        // Доступность кнопок
        ui->action_editmap->setEnabled(true);
        ui->action_closemap->setEnabled(true);
        ui->action_deletemap->setEnabled(true);
        ui->action_viewpoints->setEnabled(true);
        ui->action_viewpoints->setChecked(true);
        ui->action_viewroute->setEnabled(true);
        ui->action_viewroute->setChecked(true);
        ui->action_viewtrack->setEnabled(true);
        ui->action_currpoint->setEnabled(true);
        // Пересчёт координат точек
        foreach(Point tmpPoint, myProg->GetPointList())
            AddWayPoint(tmpPoint);
    }
    else
    {
        // Доступность кнопок
        ui->action_editmap->setEnabled(false);
        ui->action_closemap->setEnabled(false);
        ui->action_deletemap->setEnabled(false);
        ui->action_viewpoints->setEnabled(false);
        ui->action_viewpoints->setChecked(false);
        ui->action_viewroute->setEnabled(false);
        ui->action_viewroute->setChecked(false);
        ui->action_viewtrack->setEnabled(false);
        ui->action_viewtrack->setChecked(false);
        ui->action_currpoint->setEnabled(false);
        ui->action_currpoint->setChecked(false);
    }
    // Пересчёт координат точки текущего местоположения
    SetCurrPointVisible(currPointVisibility);
    UpdateCurrentRoute();
    UpdateCurrentTrack();
    UpdateSize();
}
